/* 4.12.6 1重构ValidateCodeFilter 两个合并成一个
 * 1 ValidateCodeFilter 两个合并成一个
 * 2 BrowserSecurityConfig 配置抽象
 * 3 重复字符串都被抽到了SecurityConstants接口
 * package com.imooc.security.core.validate.code;

import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.security.web.authentication.AuthenticationFailureHandler;
import org.springframework.social.connect.web.HttpSessionSessionStrategy;
import org.springframework.social.connect.web.SessionStrategy;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.bind.ServletRequestUtils;
import org.springframework.web.context.request.ServletWebRequest;
import org.springframework.web.filter.OncePerRequestFilter;

import com.imooc.security.core.properties.SecurityProperties;

*//**
 * 4.11.6 校验验证码的过滤器
 * 不用注解，而是在config的bean里创建的好处是可以被下层注解覆盖
 *//*
public class SmsCodeFilter extends OncePerRequestFilter implements InitializingBean{

	private AuthenticationFailureHandler authenticationFilterHandler;
	
	private SessionStrategy sessionStrategy = new HttpSessionSessionStrategy();
	
	private Set<String> urls = new HashSet<>();
	
	private SecurityProperties securityProperties;
	
	private AntPathMatcher pathMatcher = new AntPathMatcher();
	
	*//**
	 * 初始化设置需要验证码判断的urls
	 *//*
	@Override
	public void afterPropertiesSet() throws ServletException {
		super.afterPropertiesSet();
		String[] configUrls = StringUtils.splitByWholeSeparatorPreserveAllTokens(securityProperties.getCode().getImage().getUrl(), ",");
		for (String configUrl : configUrls) {
			urls.add(configUrl);
		}
		// 登录请求默认需要验证码
		urls.add("/authentication/mobile");
	}

	*//**
	 * 过滤方法
	 *//*
	@Override
	protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
			throws ServletException, IOException {
		
		// 如果配置的url和请求的url匹配上，就需要进行验证码过滤
		boolean action = false;
		for (String url : urls) {
			if(pathMatcher.match(url, request.getRequestURI())){
				action = true;
			}
		}
		if(action){
			try {
				validate(new ServletWebRequest(request));
			} catch (ValidateCodeException e) {
				authenticationFilterHandler.onAuthenticationFailure(request, response, e);
				return;
			}
		}
		filterChain.doFilter(request, response);
	}

	*//**
	 * 验证码校验
	 * @param servletWebRequest
	 * @throws ServletRequestBindingException 
	 *//*
	private void validate(ServletWebRequest request) throws ServletRequestBindingException {
		ValidateCode codeInSession = (ValidateCode) sessionStrategy.getAttribute(request, ValidateCodeController.SESSION_KEY_PREFIX +"SMS");

		String codeInRequest = ServletRequestUtils.getStringParameter(request.getRequest(),"smsCode");

		if (StringUtils.isBlank(codeInRequest)) {
			throw new ValidateCodeException("验证码的值不能为空");
		}

		if (codeInSession == null) {
			throw new ValidateCodeException("验证码不存在");
		}

		if (codeInSession.isExpired()) {
			sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY_PREFIX +"SMS");
			throw new ValidateCodeException("验证码已过期");
		}

		if (!StringUtils.equals(codeInSession.getCode(), codeInRequest)) {
			throw new ValidateCodeException("验证码不匹配");
		}
		
		sessionStrategy.removeAttribute(request, ValidateCodeController.SESSION_KEY_PREFIX +"SMS");
	}

	public AuthenticationFailureHandler getAuthenticationFilterHandler() {
		return authenticationFilterHandler;
	}

	public void setAuthenticationFilterHandler(AuthenticationFailureHandler authenticationFilterHandler) {
		this.authenticationFilterHandler = authenticationFilterHandler;
	}

	public SecurityProperties getSecurityProperties() {
		return securityProperties;
	}

	public void setSecurityProperties(SecurityProperties securityProperties) {
		this.securityProperties = securityProperties;
	}
	
}*/